package transhelper

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"strings"

	"gitee.com/fkil555/gin-extend/conf"
	"go.uber.org/zap"
)

func NewBaiduFanyiSpider() *SpiderBaiduFanyi {
	return &SpiderBaiduFanyi{
		ApiKey:    conf.GEConf.TransConf.ApiKey,
		SecretKey: conf.GEConf.TransConf.SecretKey,
	}
}

func (s *SpiderBaiduFanyi) GetAccessToken() string {
	url := "https://aip.baidubce.com/oauth/2.0/token"
	postData := fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", s.ApiKey, s.SecretKey)
	resp, err := http.Post(url, "application/x-www-form-urlencoded", strings.NewReader(postData))
	if err != nil {
		zap.L().Error(err.Error())
		return ""
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		zap.L().Error(err.Error())
		return ""
	}
	accessTokenObj := map[string]string{}
	json.Unmarshal([]byte(body), &accessTokenObj)
	return accessTokenObj["access_token"]
}

// ToEn
func (s *SpiderBaiduFanyi) ToEN(msg string) (string, error) {
	url := "https://aip.baidubce.com/rpc/2.0/mt/texttrans/v1?access_token=" + s.GetAccessToken()
	payload := strings.NewReader(fmt.Sprintf(`{"from":"auto","to":"en","q":"%s"}`, msg))
	client := &http.Client{}
	req, err := http.NewRequest("POST", url, payload)

	if err != nil {
		zap.L().Error(err.Error())
		return "", err
	}
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")

	res, err := client.Do(req)
	if err != nil {
		zap.L().Error(err.Error())
		return "", err
	}
	defer res.Body.Close()

	body, err := io.ReadAll(res.Body)
	if err != nil {
		zap.L().Error(err.Error())
		return "", err
	}
	var result BaiduFanyiResponse
	if err = json.Unmarshal(body, &result); err != nil {
		zap.L().Error(err.Error())
		return "", err
	}
	if result.ErrorMsg != "" {
		zap.L().Error(result.ErrorMsg)
		return "", errors.New(result.ErrorMsg)
	}
	if len(result.Result.TransResult) == 0 {
		zap.L().Error(string(body))
		return "", errors.New("百度翻译结果为空")
	}
	return result.Result.TransResult[0].Dst, nil
}

func (s *SpiderBaiduFanyi) ToFace(imageTemplatePath, imageTargetPath io.Reader) (ff FaceFusionResponse, err error) {
	templateBase64, err := encodeImageToBase64(imageTemplatePath)
	if err != nil {
		return ff, err
	}

	targetBase64, err := encodeImageToBase64(imageTargetPath)
	if err != nil {
		return ff, err
	}

	// Prepare the request payload
	payload := FaceFusionRequest{}
	payload.Version = "4.0"
	payload.ImageTemplate.Image = templateBase64
	payload.ImageTemplate.ImageType = "BASE64"
	payload.ImageTarget.Image = targetBase64
	payload.ImageTarget.ImageType = "BASE64"

	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		return ff, err
	}

	// Make the API request
	url := fmt.Sprintf("https://aip.baidubce.com/rest/2.0/face/v1/merge?access_token=%s", s.GetAccessToken())
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes))
	if err != nil {
		return ff, err
	}

	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return ff, err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return ff, err
	}

	var data FaceFusionResponse
	_ = json.Unmarshal(body, &data)

	return data, nil
}

// Function to encode image to Base64
func encodeImageToBase64(imagePath io.Reader) (string, error) {
	img, err := io.ReadAll(imagePath)
	if err != nil {
		return "", err
	}
	return base64.StdEncoding.EncodeToString(img), nil
}
